package com.letter.otools.day.diary;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.blankj.utilcode.util.TimeUtils;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.haibin.calendarview.Calendar;
import com.haibin.calendarview.CalendarLayout;
import com.haibin.calendarview.CalendarView;
import com.letter.otools.day.BaseFragment;
import com.letter.otools.day.R;
import com.letter.otools.day.user.AboutUsActivity;
import com.letter.otools.day.user.SettingActivity;
import com.letter.otools.day.search.SearchActivity;

import org.litepal.FluentQuery;
import org.litepal.LitePal;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DiaryFragment extends BaseFragment implements
        CalendarView.OnCalendarSelectListener,
        CalendarView.OnYearChangeListener {
    private Toolbar toolbar;
    private RecyclerView diaryRecyclerView;
    private FloatingActionButton fabAdd;

    private List<Diary> diaryList = new ArrayList<>();
    private TextView tvMonthDay;
    private TextView tvYear;
    private TextView tvLunar;
    private ImageView ibCalendar;
    private TextView tvCurrentDay;
    private FrameLayout flCurrent;
    private RelativeLayout rlTool;
    private CalendarView calendarView;
    private CalendarLayout calendarLayout;

    private int mYear;
    private String selectDay;
    private View noDiaryLay, noDiaryTip;

    @Override
    protected int getLayout() {
        return R.layout.diary_list;
    }

    @Override
    protected void onResultData(int resultCode, Intent intent) {
        if (resultCode == Activity.RESULT_OK) {
            this.loadData(null, true);
            this.initCalendarData();
        }
        super.onResultData(resultCode, intent);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    protected void initView(View view) {
        ((AppCompatActivity) requireActivity()).setSupportActionBar(toolbar);
//        toolbar.inflateMenu(R.menu.main);
//        setHasOptionsMenu(true);

        initCalendar();
        registerForActivityResult();
        fabAdd.setOnClickListener(v -> {
            Intent intent = new Intent(getContext(), DiaryAddActivity.class);
            intent.putExtra("selectDay", this.selectDay);
            launchForResult(intent);
        });
        noDiaryTip.setOnClickListener(view1 -> {
            Intent intent = new Intent(getContext(), DiaryAddActivity.class);
            intent.putExtra("selectDay", this.selectDay);
            launchForResult(intent);
        });
        diaryRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        diaryRecyclerView.setAdapter(diaryAdapter = new DiaryTimelineAdapter(diaryList));
        diaryAdapter.setPositionListener((p, d) -> {
            switch (p) {
                case 1:
                    Intent intent = new Intent(getActivity(), DiaryDetailActivity.class);
                    intent.putExtra("diaryId", ((Diary) d).getId());
                    launchForResult(intent);
                    break;
            }
        });
        loadData(null, true);
    }


    public static String getMonthStartDay(Date date) {
        java.util.Calendar c = java.util.Calendar.getInstance();
        c.setTime(date);
        c.set(java.util.Calendar.DAY_OF_MONTH, 1);
        SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-01");
        return startSdf.format(c.getTime());
    }

    public static String getMonthEndDay(Date date) {
        java.util.Calendar c = java.util.Calendar.getInstance();
        c.setTime(date);
        c.set(java.util.Calendar.DAY_OF_MONTH, c.getActualMaximum(java.util.Calendar.DAY_OF_MONTH));
        SimpleDateFormat endSdf = new SimpleDateFormat("yyyy-MM-dd");
        return endSdf.format(c.getTime());
    }

    Map<String, Calendar> map = new HashMap<>();

    @SuppressLint("Range")
    protected void initCalendarData() {
        Calendar calendarSelect = calendarView.getSelectedCalendar();
        int year = calendarSelect.getYear();
        int month = calendarSelect.getMonth();
        Log.e("year", String.valueOf(year));
        Log.e("month", String.valueOf(month));
        String sM = month >= 10 ? String.valueOf(month) : "0" + month;
        String yearMonth = year + "-" + sM;
        Log.e("yearMonth", yearMonth);
        Date d = TimeUtils.string2Date(yearMonth, "yyyy-MM");
        String startTime = getMonthStartDay(d);
        String endDayTime = getMonthEndDay(d);
        //查询本月的
        // 执行原生 SQL 查询
        String sql = "SELECT day,COUNT(*) AS dayNum FROM Diary where date(day) between date('" + startTime + "') and date('" + endDayTime + "') GROUP BY day ORDER BY day";
        Log.e("diary", sql);
        Cursor cursor = LitePal.findBySQL(sql);

        Map<String, Integer> dailyCounts = new HashMap<>();

        if (cursor != null && cursor.moveToFirst()) {
            do {
                String day = cursor.getString(cursor.getColumnIndex("day"));
                int count = cursor.getInt(cursor.getColumnIndex("dayNum"));
                dailyCounts.put(day, count);
            } while (cursor.moveToNext());
            cursor.close();
        }

        if (!dailyCounts.isEmpty()) {
            dailyCounts.forEach((s, integer) -> {
                java.util.Calendar calendar = java.util.Calendar.getInstance();
                Date d1 = TimeUtils.string2Date(s, "yyyy-MM-dd");
                calendar.setTime(d1);
                Log.e("diary", "s:" + s + ",i：" + integer);
                map.put(getSchemeCalendar(year, month, calendar.get(java.util.Calendar.DATE), getContext().getResources()
                                .getColor(R.color.colorTheme), String.valueOf(integer)).toString(),
                        getSchemeCalendar(year, month, calendar.get(java.util.Calendar.DATE), getContext().getResources()
                                .getColor(R.color.colorTheme), String.valueOf(integer)));
            });
        }
        //此方法在巨大的数据量上不影响遍历性能，推荐使用
        calendarView.setSchemeDate(map);
        noDiaryLay.setVisibility(diaryList.size() == 0 ? View.VISIBLE : View.GONE);
        diaryRecyclerView.setVisibility(diaryList.size() == 0 ? View.GONE : View.VISIBLE);
    }

    void initCalendar() {
        tvMonthDay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!calendarLayout.isExpand()) {
                    calendarLayout.expand();
                    return;
                }
                calendarView.showYearSelectLayout(mYear);
                tvLunar.setVisibility(View.GONE);
                tvYear.setVisibility(View.GONE);
                tvMonthDay.setText(String.valueOf(mYear));
            }
        });
        flCurrent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                calendarView.scrollToCurrent();
            }
        });


        calendarView.setOnYearChangeListener(this);
        calendarView.setOnMonthChangeListener((year, month) -> {
            initCalendarData();
        });
        calendarView.setOnCalendarSelectListener(this);
        tvYear.setText(String.valueOf(calendarView.getCurYear()));
        mYear = calendarView.getCurYear();
        tvMonthDay.setText(calendarView.getCurMonth() + "月" + calendarView.getCurDay() + "日");
        tvLunar.setText("今日");
        tvCurrentDay.setText(String.valueOf(calendarView.getCurDay()));
        selectDay = TimeUtils.millis2String(System.currentTimeMillis(), "yyyy-MM-dd");

//        diaryRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//        mRecyclerView.addItemDecoration(new GroupItemDecoration<String, Article>());
//        diaryRecyclerView.setAdapter(new ArticleAdapter(this));
//        mRecyclerView.notifyDataSetChanged();
    }

    void loadData(Integer type, boolean notify) {
        diaryList.clear();
        FluentQuery fluentQuery = LitePal.order("id asc");
        String whe = "day = ?";
        if (type != null) {
            whe += "and type = ?";
            fluentQuery.where(whe, this.selectDay, String.valueOf(type));
        } else {
            fluentQuery.where(whe, this.selectDay);
        }

        List<Diary> anniversaryList = fluentQuery.find(Diary.class);
        if (anniversaryList != null && !anniversaryList.isEmpty()) {
            this.diaryList.addAll(anniversaryList);
        }

        if (notify) {
            diaryAdapter.notifyDataSetChanged();
        }
        initCalendarData();
    }

    DiaryTimelineAdapter diaryAdapter;

    @Override
    public void initBinder(View view) {
        toolbar = view.findViewById(R.id.toolbar);
        diaryRecyclerView = view.findViewById(R.id.diaryRecyclerView);
        fabAdd = view.findViewById(R.id.fabAdd);
        tvMonthDay = view.findViewById(R.id.tv_month_day);
        tvYear = view.findViewById(R.id.tv_year);
        tvLunar = view.findViewById(R.id.tv_lunar);
        ibCalendar = view.findViewById(R.id.ib_calendar);
        tvCurrentDay = view.findViewById(R.id.tv_current_day);
        flCurrent = view.findViewById(R.id.fl_current);
        rlTool = view.findViewById(R.id.rl_tool);
        calendarView = view.findViewById(R.id.calendarView);
        calendarLayout = view.findViewById(R.id.calendarLayout);
        noDiaryLay = view.findViewById(R.id.noDiaryLay);
        noDiaryTip = view.findViewById(R.id.noDiaryTip);
    }


    private Calendar getSchemeCalendar(int year, int month, int day, int color, String text) {
        Calendar calendar = new Calendar();
        calendar.setYear(year);
        calendar.setMonth(month);
        calendar.setDay(day);
        calendar.setSchemeColor(color);//如果单独标记颜色、则会使用这个颜色
        calendar.setScheme(text);
        return calendar;
    }

    @Override
    public void onCalendarOutOfRange(Calendar calendar) {

    }

    @Override
    public void onCalendarSelect(Calendar calendar, boolean isClick) {
        tvLunar.setVisibility(View.VISIBLE);
        tvYear.setVisibility(View.VISIBLE);
        tvMonthDay.setText(calendar.getMonth() + "月" + calendar.getDay() + "日");
        tvYear.setText(String.valueOf(calendar.getYear()));
        tvLunar.setText(calendar.getLunar());
        mYear = calendar.getYear();
        selectDay = TimeUtils.millis2String(calendar.getTimeInMillis(), "yyyy-MM-dd");
        loadData(null, true);
    }

    @Override
    public void onYearChange(int year) {
        tvMonthDay.setText(String.valueOf(year));
    }


    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        inflater.inflate(R.menu.main, menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.action_settings) {
            startActivity(new Intent(getContext(), SettingActivity.class));
            return true;
        } else if (itemId == R.id.action_About) {
            startActivity(new Intent(getContext(), AboutUsActivity.class));
            return true;
        } else if (itemId == R.id.action_search) {
            startActivity(new Intent(getContext(), SearchActivity.class));
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
